#include "TheApp.hpp"
#include "cybertron/core/Log.hpp"
#include "cybertron/core/SimOneEnv.hpp"
#include "cybertron/core/logServer.hpp"
#include "cybertron/core/JsonReader.hpp"
#include "MasterServer.hpp"
#include "NodeAgentManger.hpp"
#include "NodeCommanderManger.hpp"
#include "cybertron/core/UtilConsole.hpp"
#include "cybertron/core/UtilCRT.hpp"
#include "cybertron/core/ConfigureClient.hpp"
#include "cybertron/node/StartupArguments.hpp"
#include "cybertron/core/CoreVersion.hpp"
#include "TaskManager.hpp"
#include "cybertron/core/K8SDevOpsInfo.hpp"
using namespace cybertron;

static UtilCRTAutoInitialize sCRT;

TheApp::TheApp()
{
	BaseApp::mInstance = this;
	
}



void TheApp::InitNodeInfo() {

	if (SimOneEnv::GetInstance().IsCloudEnv()) {

		SimOneEnv::SimOneCloudEnvInfo CloundEnvInfo;
		SimOneEnv::GetInstance().GetCloundEnvInfo(CloundEnvInfo);

		mGroupId = "";
		mId = CloundEnvInfo.PodName;
		mType = Common::EWorkNodeType_CybertronMaster;

		mDescription = "";
		mUserData = "";
		mTag = SimOneEnv::GetInstance().GetPodTagString();

		mUserData = CloundEnvInfo.PodIP;
		mUserData += ":";
		mUserData += std::to_string(mListenPort);
		mTaskRunnerPoolClient.enable(true);

		SimOneEnv::SimOneTaskRunnerPoolServerInfo serverInfo;
		SimOneEnv::GetInstance().GetTaskRunnerPoolInfo(serverInfo);
		//SimOneSONServerInfo
		mTaskRunnerPoolClient.setServerInfo(serverInfo.SONServerAddr, serverInfo.SONServerAddrPort);
	}
	else {
		std::thread::id thread_id = std::this_thread::get_id();

		stringstream ss;
		ss << thread_id;

		mGroupId = "";
		mId = ss.str();
		mType = Common::EWorkNodeType_CybertronMaster;
		mDescription = "";
		
		mUserData = "127.0.0.1";
		mUserData += ":";
		mUserData += std::to_string(mListenPort);
		mTag = "";
		mTaskRunnerPoolClient.enable(false);
	}
	
	mTaskRunnerPoolClient.initialize(mGroupId, mType, mId, mDescription, mUserData, mTag);	
}
void TheApp::taskPreAllocate(string taskId) {
	if (SimOneEnv::GetInstance().IsCloudEnv()) {
		K8SDevOps::GetInstance().BindPod(taskId);
	}
	mTaskRunnerPoolClient.updateTaskStateToServer(TaskRunnerPool::ETaskRunnerPoolStatePreDo);
}
void TheApp::taskStart(string taskId) {
	mTaskRunnerPoolClient.updateTaskStateToServer(TaskRunnerPool::ETaskRunnerPoolStateDoing);
}

void TheApp::taskStop(string taskId) {
	if (SimOneEnv::GetInstance().IsCloudEnv()) {
		K8SDevOps::GetInstance().DeleteSelfPod();
		mTaskRunnerPoolClient.updateTaskStateToServer(TaskRunnerPool::ETaskRunnerPoolStateDone);
	}
	else {
		mTaskRunnerPoolClient.updateTaskStateToServer(TaskRunnerPool::ETaskRunnerPoolStateReadying);
	}
	
}

int TheApp::parseArguments(int argc, char* argv[])
{
	if (argc != 2)
	{
		logOutputError("", "Usage: CybertronCoordinator <port>");
		return 0;
	}

	mListenPort = std::atoi(argv[1]);

	return 0;
}

void TheApp::getVerion()
{
	std::string version = getVersionOnCore("CybertronCoordinator", "20210517111111");
	printf("%s", version.c_str());
}


int TheApp::beforeRun()
{
	cybertron::setupLogFile("Master");
	UtilConsole::setTitle("Master");
	UtilConsole::setColor(EConsoleColor_Green, EConsoleColor_Black);
	
	InitNodeInfo();

	return 0;
}
int TheApp::checkStateThread() {
	while (true)
	{
		std::this_thread::sleep_for(std::chrono::seconds(3));

		if (NodeAgentManger::GetInstance().IsHasAgentFree()) {
			TaskRunnerPool::ETaskRunnerPoolState state = mTaskRunnerPoolClient.getState();
			if (state == TaskRunnerPool::ETaskRunnerPoolStateReadying) {
				mTaskRunnerPoolClient.updateTaskStateToServer(TaskRunnerPool::ETaskRunnerPoolStateFree);
			}
		}
	}
}
int TheApp::run()
{

	std::thread thread(&TheApp::checkStateThread, this);
	thread.detach();

	mMasterServer = std::make_shared<MasterServer>();
	mMasterServer->SetListenPort(mListenPort);
	mMasterServer->listen(mListenPort);
	mMasterServer->run();

	return 0;
}
